package com.anxin.act.task.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.anxin.act.cmd.DeleteRuTaskCmd;
import com.anxin.act.cmd.StartActCmd;
import com.anxin.act.model.service.WfActApproverService;
import com.anxin.act.process.service.ActFreeFlowService;
import com.anxin.act.process.service.ActProcessService;
import com.anxin.act.process.service.FlowInterfacesService;
import com.anxin.act.process.service.ProcessEndService;
import com.anxin.act.task.complete.TaskComplete;
import com.anxin.act.task.complete.TaskCompleteFactory;
import com.anxin.act.task.complete.impl.FreeFlowCompleteImpl;
import com.anxin.act.task.dao.*;
import com.anxin.act.task.entity.*;
import com.anxin.act.task.vo.FormPropertyVo;
import com.anxin.act.task.vo.HistoryNodeVo;
import com.anxin.act.task.vo.TaskVo;
import com.anxin.act.utils.ActProcessUtils;
import com.anxin.act.utils.ActTaskUtils;
import com.anxin.act.utils.ActUtils;
import com.anxin.act.wfEntrustTask.service.WfEntrustTaskService;
import com.anxin.common.utils.DateUtils;
import com.anxin.common.utils.LogUtils;
import com.anxin.common.utils.StringUtils;
import com.anxin.common.utils.qiyuesuo.QysInterfaceUtils;
import com.anxin.common.utils.sys.UserUtils;
import com.anxin.confirmnotificationsrv.InputParameters;
import com.anxin.confirmnotificationsrv.OSBBPWFPHQImportConfirmNotificationSrv;
import com.anxin.confirmnotificationsrv.OSB_BP_WFP_HQ_ImportConfirmNotificationSrvClient;
import com.anxin.confirmnotificationsrv.OutputParameters;
import com.anxin.framework.redis.MqProducer;
import com.anxin.framework.redis.RedisCache;
import com.anxin.framework.redis.RedisMq;
import com.anxin.framework.web.entity.AjaxResult;
import com.anxin.osbProinstInfor.entity.OsbProinstInfor;
import com.anxin.osbProinstInfor.service.OsbProinstInforService;
import com.anxin.sys.file.dao.FileBaseDao;
import com.anxin.sys.file.entity.FileBase;
import com.anxin.sys.file.service.FileBaseService;
import com.anxin.sys.message.dao.MsgBaseDao;
import com.anxin.sys.message.service.MessageCountService;
import com.anxin.sys.sql.dao.SqlDao;
import com.anxin.sys.system.entity.SysUser;
import com.anxin.sys.system.utils.ConfigUtils;
import org.activiti.engine.FormService;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.delegate.Expression;
import org.activiti.engine.form.FormProperty;
import org.activiti.engine.form.TaskFormData;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.impl.bpmn.behavior.ParallelGatewayActivityBehavior;
import org.activiti.engine.impl.bpmn.behavior.ParallelMultiInstanceBehavior;
import org.activiti.engine.impl.bpmn.behavior.SequentialMultiInstanceBehavior;
import org.activiti.engine.impl.bpmn.behavior.UserTaskActivityBehavior;
import org.activiti.engine.impl.persistence.entity.TaskEntity;
import org.activiti.engine.impl.pvm.PvmActivity;
import org.activiti.engine.impl.pvm.PvmTransition;
import org.activiti.engine.impl.pvm.delegate.ActivityBehavior;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.task.TaskDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Attachment;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * 任务处理
 *
 * @author: liuxiangyu
 * @date: 2020/3/18 16:09
 */
@Service
public class ActTaskService implements RedisMq, MessageCountService {
    @Autowired
    private TaskService taskService;
    @Autowired
    private HistoryService historyService;
    @Autowired
    private FormService formService;
    @Autowired
    private FileBaseService fileBaseService;
    @Autowired
    private FileBaseDao fileBaseDao;
    @Autowired
    private TaskCompleteFactory taskCompleteFactory;
    @Autowired
    private ActFreeFlowService actFreeFlowService;
    @Autowired
    private ActTaskDao actTaskDao;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private ViewRuTaskService viewRuTaskService;
    @Autowired
    private ViewHiTaskService viewHiTaskService;
    @Autowired
    private WfActRuTaskService wfActRuTaskService;
    @Autowired
    private WfActHiTaskService wfActHiTaskService;
    @Autowired
    private AddTaskService addTaskService;
    @Autowired
    private WfActRuTaskDao wfActRuTaskDao;
    @Autowired
    private WfActHiTaskDao wfActHiTaskDao;
    @Autowired
    private WfActHiCommentDao wfActHiCommentDao;
    @Autowired
    private WfCcRecordDao wfCcRecordDao;
    @Autowired
    private WfEntrustTaskService wfEntrustTaskService;
    @Autowired
    private MqProducer mqProducer;
    @Autowired
    private ActDockingService actDockingService;
    @Autowired
    private WfActHiCommentService wfActHiCommentService;
    @Autowired
    private SqlDao sqlDao;
    @Autowired
    private WfCommentStagingService wfCommentStagingService;
    @Autowired
    private ActHiCommentService actHiCommentService;
    @Autowired
    private WfTaskReadService wfTaskReadService;
    @Autowired
    private WfActTaskVariableService wfActTaskVariableService;
    @Autowired
    private ActSpecialTaskService actSpecialTaskService;
    @Autowired
    private ActSendTaskService actSendTaskService;
    @Autowired
    private ActSendCcService actSendCcService;
    @Autowired
    private ProcessEndService processEndService;
    @Autowired
    private MsgBaseDao msgBaseDao;
    @Autowired
    private FlowInterfacesService flowInterfacesService;
    @Autowired
    private FreeFlowCompleteImpl freeFlowCompleteImpl;
    @Autowired
    private ActProcessService actProcessService;
    @Autowired
    private OsbProinstInforService osbProinstInforService;

    /**
     * 查询待办
     */
    public List<ViewRuTask> todoList(ViewRuTask viewRuTask) {
        viewRuTask.setAssigneeList(wfEntrustTaskService.findEntrustUserName());
        viewRuTask.setHang("N");

        // 申请人查询条件
        if (StringUtils.isNotBlank(viewRuTask.getApplyUserId())) {
            viewRuTask.setApplyLoginName(UserUtils.getUser(viewRuTask.getApplyUserId()).getUserName());
        }

        List<ViewRuTask> viewRuTaskList = viewRuTaskService.findPage(viewRuTask);

        for (ViewRuTask ruTask : viewRuTaskList) {
            // 流程是否加急
            ruTask.setUrgent(ActProcessUtils.getProcessVar(ruTask.getActId(), "urgent"));
            // 查询是否未读
            boolean readStatus = this.getReadStatus(ruTask.getId(), ruTask.getAssigneeId());
            ruTask.setReadStatus(readStatus);
        }

        return viewRuTaskList;
    }




    /**
     * 查询已办列表
     *
     * @param taskVo
     * @return
     */
    public List<ViewHiTask> hiList(TaskVo taskVo) {
        ViewHiTask viewHiTask = new ViewHiTask(taskVo);

        // 申请人查询条件
        if (StringUtils.isNotBlank(taskVo.getApplyUserId())) {
            viewHiTask.setApplyLoginName(UserUtils.getUser(taskVo.getApplyUserId()).getUserName());
        }

        viewHiTask.setAssignee(UserUtils.getUser().getUserName());
        viewHiTask.setQueryType("hiTask");
        viewHiTask.setOrderByColumn(" a.approval_time desc ");
        return viewHiTaskService.findPage(viewHiTask);
    }

    /**
     * 修改历史任务时间
     * @param taskId 任务ID
     * @param startTime 开始时间
     * @param endTime 结束时间
     */
    public void updateHiTaskTime(String taskId, Date startTime, Date endTime){
        actTaskDao.updateActHiActInstTime(taskId,startTime,endTime);
        actTaskDao.updateActHiTaskTime(taskId,startTime,endTime);
    }


    /**
     * 撤回任务校验
     *
     * @param taskId 任务ID
     * @return
     */
    public AjaxResult withdrawCheck(String taskId) {
        // 查询当前任务

        ViewHiTask viewHiTask = viewHiTaskService.get(taskId);

        // 如果是委托处理任务，则用原任务查询
        if ("entrust".equals(viewHiTask.getType())) {
            WfActHiTask wfActHiTask = wfActHiTaskService.get(viewHiTask.getId());
            viewHiTask = viewHiTaskService.get(wfActHiTask.getSourceId());
            if ("actTask".equals(viewHiTask.getType())){
                return AjaxResult.setSuccessData("节点已合并至原始节点，无法撤回");
            }
        }

        ProcessInstance processInstance = ActProcessUtils.getProcessInstance(viewHiTask.getActId());
        if (processInstance == null) {

            return AjaxResult.setSuccessData("流程已结束或终止,无法撤回");
        }

        if ("act_free_flow_approval".equals(processInstance.getProcessDefinitionKey()) || "act_self_built_process".equals(processInstance.getProcessDefinitionKey())) {
            return AjaxResult.setSuccessData("自由流与自建流程暂时无法撤回");
        }


        if ("actTask".equals(viewHiTask.getType())) {
            return AjaxResult.setSuccessData(this.withdrawCheckActTask(viewHiTask));
        } else {
            return AjaxResult.setSuccessData(this.withdrawCheckAddTask(viewHiTask));
        }

    }

    /**
     * 撤回任务
     *
     * @param taskId 任务ID
     * @return
     */
    public void withdrawTask(String taskId) {
        // 查询当前任务
        ViewHiTask viewHiTask = viewHiTaskService.get(taskId);

        // 是否是委托任务撤回
        boolean isEntrust = false;

        // 如果是委托处理任务，则用原任务查询
        if ("entrust".equals(viewHiTask.getType())) {
            isEntrust = true;
            WfActHiTask wfActHiTask = wfActHiTaskService.get(viewHiTask.getId());
            viewHiTask = viewHiTaskService.get(wfActHiTask.getSourceId());
        }

        if ("actTask".equals(viewHiTask.getType())) { // 正常Activity任务
            this.withdrawActTask(viewHiTask);
        } else {
            this.withdrawAddTask(viewHiTask);
        }
        ActTaskUtils.claimTask(viewHiTask.getActId());

        // 删除之前的已办
        actDockingService.delHiTask(viewHiTask);

        // 如果是委托任务撤回,删除该委托处理记录
        if (isEntrust) {
            wfActHiTaskService.deleteById(taskId);
        }

        // 删除抄送信息
        wfCcRecordDao.delByTaskId(taskId);
        // 删除抄送记录
        msgBaseDao.delByParameters(taskId);
        // 删除附件
        fileBaseDao.deleteFileByDataId(taskId);


        // 对接待办推送
        mqProducer.sendMessage(ActDockingService.class, viewHiTask.getActId());

    }


    /**
     * 撤回加签任务
     *
     * @param viewHiTask
     */
    public void withdrawAddTask(ViewHiTask viewHiTask) {
        WfActHiTask wfActHiTask = wfActHiTaskService.get(viewHiTask.getId());
        String taskId = wfActHiTask.getId();

        if ("comment".equals(wfActHiTask.getSourceType())) {
            taskId = wfActHiTask.getSourceId();
            wfActHiTask = wfActHiTaskService.get(taskId);
        }

        // 删除审批意见
        wfActHiCommentDao.delByTaskId(viewHiTask.getId());

        // 删除该节点加签产生的任务
        wfActHiTaskService.delBySourceId(taskId);
        wfActRuTaskService.delBySourceId(taskId);


        // 如果是前加签则挂起原任务


        // 恢复任务
        WfActRuTask wfActRuTask = new WfActRuTask(wfActHiTask);
        // 查询相关任务是否还存在
//        Task task = ActTaskUtils.getTask(wfActRuTask.getActTaskId());
//        if (task == null){
//
//            // 查询历史任务对象
//            HistoricTaskInstance hiTask = ActTaskUtils.getHiTask(viewHiTask.getTaskId());
//            // 查询历史任务对应的Activity对象
//            ActivityImpl activityImpl = ActUtils.getActivityImpl(hiTask.getProcessDefinitionId(), hiTask.getTaskDefinitionKey());
//            // 撤回节点
//            boolean withdrawNode = true;
//
//            // 撤回后续任务
//            this.withdrawSubsequentTask(hiTask,activityImpl,viewHiTask,withdrawNode);
//
//            // 撤回因驳回产生的任务
//            this.withdrawRejectedTask(hiTask,activityImpl,viewHiTask,withdrawNode);
//
//            // 撤回驳回至当前节点并且驳回时设置驳回方式为回到当前你节点的节点
//            this.withdrawRejectedCompleteTask(hiTask,activityImpl,viewHiTask,withdrawNode);
//        }
//

        wfActRuTask.setHang("N");
        WfActRuTask wfActRuTaskTemp = wfActRuTaskDao.getById(wfActRuTask.getId());
        if (wfActRuTaskTemp == null){
            wfActRuTaskDao.insert(wfActRuTask);
        }else {
            wfActRuTaskDao.update(wfActRuTask);
        }

        wfActHiTaskDao.deleteById(wfActHiTask.getId());
        wfActHiTask.setApprovalTime(null);
        wfActHiTask.setHang("N");
        wfActHiTaskDao.insert(wfActHiTask);


        ViewRuTask sourceViewRuTask = viewRuTaskService.get(wfActRuTask.getSourceId());
        if (sourceViewRuTask != null) {
            addTaskService.hangTask(sourceViewRuTask);
        }

    }


    /**
     * 撤回任务
     *
     * @param viewHiTask 任务
     */
    public void withdrawActTask(ViewHiTask viewHiTask) {
        // 查询历史任务对象
        HistoricTaskInstance hiTask = ActTaskUtils.getHiTask(viewHiTask.getTaskId());
        // 查询历史任务对应的Activity对象
        ActivityImpl activityImpl = ActUtils.getActivityImpl(hiTask.getProcessDefinitionId(), hiTask.getTaskDefinitionKey());

        // 撤回节点
        boolean withdrawNode = true;

        // 撤回后续任务
        this.withdrawSubsequentTask(hiTask, activityImpl, viewHiTask, withdrawNode);

        // 撤回因驳回产生的任务
        this.withdrawRejectedTask(hiTask, activityImpl, viewHiTask, withdrawNode);

        // 撤回驳回至当前节点并且驳回时设置驳回方式为回到当前你节点的节点
        this.withdrawRejectedCompleteTask(hiTask, activityImpl, viewHiTask, withdrawNode);

        // 删除加签记录
        wfActRuTaskService.delAllByTaskId(viewHiTask);
        wfActHiTaskService.delAllByTaskId(viewHiTask);

        // 如果任务被挂起则恢复任务
        if ("-2".equals(hiTask.getAssignee())) {
            addTaskService.restoreTask(hiTask.getId());
        } else {
            // 删除之前的审批记录
            actTaskDao.delHiTaskInst(hiTask.getId());
        }

    }

    /**
     * 撤回驳回至当前节点并且驳回时设置驳回方式为回到当前你节点的节点
     *
     * @param hiTask       当前历史对应的activity任务
     * @param activityImpl 当前历史任务对应的  activityImpl
     * @param viewHiTask   当前历史任务
     * @param withdrawNode 是否需要新任务
     */
    public void withdrawRejectedCompleteTask(HistoricTaskInstance hiTask, ActivityImpl activityImpl, ViewHiTask viewHiTask, boolean withdrawNode) {
        HistoricTaskInstance historicTaskInstance = ActTaskUtils.getHiTask(viewHiTask.getId());
        if (historicTaskInstance != null) {
            if (historicTaskInstance.getTaskLocalVariables().get("rejectedCompleteType") != null && "current".equals(historicTaskInstance.getTaskLocalVariables().get("rejectedCompleteType").toString())) {
                List<Task> rejectedTaskList = taskService.createTaskQuery().processInstanceId(viewHiTask.getActId()).taskDefinitionKey(historicTaskInstance.getTaskLocalVariables().get("rejectedCompleteNode").toString()).list();
                for (int i1 = 0; i1 < rejectedTaskList.size(); i1++) {
                    if (withdrawNode) {
                        ActUtils.executeCommand(new StartActCmd(rejectedTaskList.get(i1).getExecutionId(), activityImpl));

                        List<Task> list = taskService.createTaskQuery().processInstanceId(viewHiTask.getActId()).executionId(rejectedTaskList.get(i1).getExecutionId()).taskDefinitionKey(activityImpl.getId()).includeTaskLocalVariables().active().list();
                        for (Task task : list) {
                            taskService.setVariablesLocal(task.getId(), hiTask.getTaskLocalVariables());
                        }

                        withdrawNode = false;
                    }
                    ActUtils.executeCommand(new DeleteRuTaskCmd((TaskEntity) rejectedTaskList.get(i1)));
                    // 删除之前的审批记录
                    this.delHiTaskInst(rejectedTaskList.get(i1).getId());
                }
            }
        }
    }

    /**
     * 撤回通过当前任务驳回产生的任务
     *
     * @param hiTask       当前历史对应的activity任务
     * @param activityImpl 当前历史任务对应的  activityImpl
     * @param viewHiTask   当前历史任务
     * @param withdrawNode 是否需要新任务
     */
    public void withdrawRejectedTask(HistoricTaskInstance hiTask, ActivityImpl activityImpl, ViewHiTask viewHiTask, boolean withdrawNode) {
        List<Task> taskList = taskService.createTaskQuery().processInstanceId(viewHiTask.getActId()).taskVariableValueEquals("rejectedCompleteNode", hiTask.getTaskDefinitionKey()).active().list();
        for (Task task : taskList) {
            if (task.getCreateTime().getTime() >= hiTask.getEndTime().getTime()) {
                if (withdrawNode) {
                    ActUtils.executeCommand(new StartActCmd(task.getExecutionId(), activityImpl));
                    List<Task> list = taskService.createTaskQuery().processInstanceId(viewHiTask.getActId()).executionId(task.getExecutionId()).taskDefinitionKey(activityImpl.getId()).includeTaskLocalVariables().active().list();
                    for (Task taskinfo : list) {
                        taskService.setVariablesLocal(taskinfo.getId(), hiTask.getTaskLocalVariables());
                    }

                    withdrawNode = false;
                }
                ActUtils.executeCommand(new DeleteRuTaskCmd((TaskEntity) task));
                // 删除之前的审批记录
                this.delHiTaskInst(task.getId());
            }

        }
    }

    /**
     * 撤回后续任务
     *
     * @param hiTask       当前历史对应的activity任务
     * @param activityImpl 当前历史任务对应的  activityImpl
     * @param viewHiTask   当前历史任务
     * @param withdrawNode 是否需要新任务
     */
    public void withdrawSubsequentTask(HistoricTaskInstance hiTask, ActivityImpl activityImpl, ViewHiTask viewHiTask, boolean withdrawNode) {
        // 撤回节点
        // 查询该节点之后的节点
        List<ActivityImpl> userTaskActList = ActUtils.getOutgoingActivity(hiTask.getProcessDefinitionId(), hiTask.getTaskDefinitionKey());
        for (int i = 0; i < userTaskActList.size(); i++) {
            ActivityImpl activity = userTaskActList.get(i);
            List<Task> taskList = taskService.createTaskQuery().processInstanceId(viewHiTask.getActId()).taskDefinitionKey(activity.getId()).list();
            for (int i1 = 0; i1 < taskList.size(); i1++) {
                if (withdrawNode) {
                    ActUtils.executeCommand(new StartActCmd(taskList.get(i1).getExecutionId(), activityImpl));
                    withdrawNode = false;
                }
                ActUtils.executeCommand(new DeleteRuTaskCmd((TaskEntity) taskList.get(i1)));
                // 删除之前的审批记录
                this.delHiTaskInst(taskList.get(i1).getId());
            }
        }
    }


    /**
     * activiti任务-撤回校验
     *
     * @param viewHiTask
     * @return
     */
    public String withdrawCheckActTask(ViewHiTask viewHiTask) {
        StringBuffer message = new StringBuffer();
        HistoricTaskInstance hiTask = ActTaskUtils.getHiTask(viewHiTask.getTaskId());

        ActivityImpl activityImpl = ActUtils.getActivityImpl(hiTask.getProcessDefinitionId(), hiTask.getTaskDefinitionKey());

        if (activityImpl.getActivityBehavior() instanceof ParallelMultiInstanceBehavior) {
            return "会签节点,无法撤回";
        }

        // 查询该节点之后的节点
        List<ActivityImpl> userTaskActList = ActUtils.getOutgoingActivity(hiTask.getProcessDefinitionId(), hiTask.getTaskDefinitionKey());


        // 查询该节点之后的节点是否有审批
        for (ActivityImpl activity : userTaskActList) {
            // 查询到并行网关
            if (activity.getActivityBehavior() instanceof ParallelGatewayActivityBehavior) {
                return "分支已合并至并行网关，无法撤回";
            } else {
                List<HistoricTaskInstance> historicTaskInstanceList = historyService.createHistoricTaskInstanceQuery().processInstanceId(viewHiTask.getActId()).taskDefinitionKey(activity.getId()).list();
                for (HistoricTaskInstance historicTaskInstance : historicTaskInstanceList) {

                    if ("-2".equals(historicTaskInstance.getAssignee()) || (historicTaskInstance.getEndTime() != null && viewHiTask.getStartTime().getTime() <= historicTaskInstance.getStartTime().getTime())) {
                        SysUser user = UserUtils.getUserByUserName(historicTaskInstance.getAssignee());
                        String userNickName = user != null ? "(" + user.getNickName() + ")" : "";
                        StringUtils.bufferAppend(message, historicTaskInstance.getName() + userNickName, ",");
                    }
                }
            }
        }

        // 查询驳回的节点
        List<HistoricTaskInstance> rejectedCompleteNodeList = historyService.createHistoricTaskInstanceQuery().processInstanceId(viewHiTask.getActId()).taskVariableValueEquals("rejectedCompleteNode", hiTask.getTaskDefinitionKey()).list();
        for (HistoricTaskInstance task : rejectedCompleteNodeList) {
            if (hiTask.getEndTime() != null && task.getCreateTime().getTime() >= hiTask.getEndTime().getTime()) {
                HistoricTaskInstance rejectedHiTask = ActTaskUtils.getHiTask(task.getId());
                if (rejectedHiTask.getEndTime() != null) {
                    SysUser user = UserUtils.findByUserNameContainsDelete(rejectedHiTask.getAssignee());
                    String userNickName = user != null ? "(" + user.getNickName() + ")" : "";
                    StringUtils.bufferAppend(message, rejectedHiTask.getName() + userNickName, "<br>");
                }
            }
        }

        // 撤回驳回至当前节点并且驳回时设置驳回方式为回到当前你节点的节点
        String rejectedCompleteType = hiTask.getTaskLocalVariables().get("rejectedCompleteType") != null ? hiTask.getTaskLocalVariables().get("rejectedCompleteType").toString() : "";
        if ("current".equals(rejectedCompleteType)) {
            List<HistoricTaskInstance> rejectedNodeList = historyService.createHistoricTaskInstanceQuery().processInstanceId(hiTask.getProcessInstanceId()).taskDefinitionKey(hiTask.getTaskLocalVariables().get("rejectedCompleteNode").toString()).list();
            for (HistoricTaskInstance historicTaskInstance : rejectedNodeList) {
                if (hiTask.getEndTime() != null && historicTaskInstance.getCreateTime().getTime() >= hiTask.getEndTime().getTime()) {
                    HistoricTaskInstance hiTask1 = ActTaskUtils.getHiTask(historicTaskInstance.getId());
                    if (hiTask1.getEndTime() != null) {
                        SysUser user = UserUtils.findByUserNameContainsDelete(hiTask1.getAssignee());
                        String userNickName = user != null ? "(" + user.getNickName() + ")" : "";
                        StringUtils.bufferAppend(message, hiTask1.getName() + userNickName, "<br>");
                    }
                }
            }

        }

        WfActHiTask wfActHiTask = wfActHiTaskDao.getById(viewHiTask.getId());
        if (wfActHiTask != null && "comment".equals(wfActHiTask.getSourceType())) {
            List<WfActHiTask> wfActHiTaskList = wfActHiTaskDao.findBySourceId(wfActHiTask.getSourceId());
            System.err.println(DateUtils.format("yyyy-MM-dd HH:mm:ss",wfActHiTask.getApprovalTime()));
            for (WfActHiTask task : wfActHiTaskList) {
                System.err.println(DateUtils.format("yyyy-MM-dd HH:mm:ss",task.getCreateTime()));
                if (task.getApprovalTime() != null && !viewHiTask.getId().equals(task.getId()) && task.getStartTime().getTime() > wfActHiTask.getApprovalTime().getTime()) {
                    message.append("加签任务");
                }
            }
        }


        if (StringUtils.isNotBlank(message)) {
            message.append("已审批,无法撤回");
        }

        return message.toString();
    }

    /**
     * 加签任务-撤回校验
     *
     * @param viewHiTask
     * @return
     */
    public String withdrawCheckAddTask(ViewHiTask viewHiTask) {
        StringBuffer message = new StringBuffer();
        HistoricTaskInstance hiTask = ActTaskUtils.getHiTask(viewHiTask.getTaskId());

        List<WfActHiTask> wfActHiTaskList = wfActHiTaskDao.findBySourceId(viewHiTask.getId());

        for (WfActHiTask wfActHiTask : wfActHiTaskList) {
            if (wfActHiTask.getApprovalTime() != null) {
                message.append("后续加签节点已审批，无法撤回");
            }

        }

        if (hiTask != null && hiTask.getEndTime() != null) {
            if ("-2".equals(hiTask.getAssignee())) {

                List<HistoricTaskInstance> rejectedCompleteNodeList = historyService.createHistoricTaskInstanceQuery().processInstanceId(viewHiTask.getActId()).taskVariableValueEquals("rejectedCompleteTaskId", viewHiTask.getId()).list();

                if (rejectedCompleteNodeList.size() > 0) {
                    for (HistoricTaskInstance historicTaskInstance : rejectedCompleteNodeList) {
                        if (historicTaskInstance.getEndTime() != null) {
                            message.append("驳回节点已审批无法撤回");
                        }
                    }
                } else {
                    message.append("节点被其他用户驳回或加签节点已合并至原始节点，无法撤回");
                }

            } else {
                message.append("加签节点已合并至原始节点，无法撤回");
            }

            if (StringUtils.isBlank(message)) {
                message.append("加签任务驳回后无法撤回");
            }
        }


        return message.toString();
    }

    /**
     * 获取业务表单地址
     * @param taskVo 任务对象
     * @param activityImpl activityImpl对象
     * @return
     */
    public JSONArray getFormPath(TaskVo taskVo,ActivityImpl activityImpl){
        // 电子签章签约节点
        if ("true".equals(activityImpl.getProperty("electronicseal"))){
            String dataId = ActUtils.getDataId(taskVo.getActId());
            String contractId = sqlDao.getFieldValue("fund_electronic_seals", "contract_id", dataId);
            String pageUrl = QysInterfaceUtils.getPageUrl(Long.parseLong(contractId));
            JSONObject data = new JSONObject();
            data.put("iframeSrc",pageUrl);
            String viewUrl = "@/views/tool/iframe/iframe";
            taskVo.addBusinessPathArray("文件签署",viewUrl,data);
        }
        return null;
    }

    /**
     * 获取待办信息
     *
     * @param id
     * @return
     */
    public TaskVo getTask(String id) {

        // 获取任务对象
        TaskVo taskVo = this.getTaskVo(id);
        // 将任务修改为已读状态
        this.updateReadStatus(taskVo);

        // 未完成的任务才查询字段
        //if (((HistoricTaskInstance) taskInfo).getEndTime() == null){
//        taskVo.setFormFieldList(this.getFormFiled(taskVo.getId(), taskVo.getTaskId()));
        // }


        // 获取Activity参数
        this.setActivityParam(taskVo);

        // 查询审批字段暂存信息
        wfCommentStagingService.loadingByTaskBy(taskVo);

        // 如果是自由流查询下一审批人
        actFreeFlowService.getNextApproval(taskVo);

        // 设置临时权限，供用户查看待办表单
        redisCache.setCacheObject("act_permissions_" + UserUtils.getUser().getId(), "act", 5, TimeUnit.MINUTES);
        return taskVo;
    }

    /**
     * 查询待办信息
     *
     * @param id
     * @return
     */
    public TaskVo getTaskVo(String id) {
        TaskVo taskVo = null;

        ViewRuTask viewRuTask = viewRuTaskService.get(id);
        if(viewRuTask == null){
            OsbProinstInfor byProInst = osbProinstInforService.getByProInst(id);
            if(byProInst != null){
                TaskEntity currentTask = ActTaskUtils.getCurrentTask(byProInst.getProcessinstId());
                viewRuTask = viewRuTaskService.get(currentTask.getId());
                id = currentTask.getId();
            }
        }
        // activiti 任务
        if ("actTask".equals(viewRuTask.getType())) {
            TaskInfo taskInfo = historyService.createHistoricTaskInstanceQuery().taskId(id).includeProcessVariables().singleResult();
            taskVo = new TaskVo(taskInfo).initRuData();
        } else {
            TaskInfo taskInfo = historyService.createHistoricTaskInstanceQuery().taskId(viewRuTask.getTaskId()).includeProcessVariables().singleResult();
            taskVo = new TaskVo(taskInfo, viewRuTask).initRuData();
        }

        return taskVo;
    }

    /**
     * 获取Activity参数
     *
     * @param taskVo
     */
    public void setActivityParam(TaskVo taskVo) {
        ActivityImpl activityImpl = ActUtils.getActivityImpl(taskVo.getProcessDefId(), taskVo.getTaskKey());
        Map<String, Object> properties = activityImpl.getProperties();


        // 查询审批字段
        taskVo.setFormFieldList(this.getFormFiled(taskVo.getId(),taskVo.getTaskId(),taskVo.getActId(),activityImpl));

        // 是否可以修改表单
        taskVo.setActModifyFrom(properties.get("actmodifyfrom") != null ? properties.get("actmodifyfrom").toString() : "false");

        // 加签节点看下是否单独设置了是否可以修改表单，如果设置了用加签节点的，目前用于申请人补充材料功能
        if (!"actTask".equals(taskVo.getTaskType())) {
            WfActRuTask wfActRuTask = wfActRuTaskService.get(taskVo.getId());
            if (wfActRuTask != null && StringUtils.isNotBlank(wfActRuTask.getActModifyFrom())) {
                taskVo.setActModifyFrom(wfActRuTask.getActModifyFrom());
            }
        }


        // 是否为下一节点选择审批人
        taskVo.setSelectApproval(properties.get("selectapproval") != null ? properties.get("selectapproval").toString() : "false");
        // 是否可以查看审批记录
        taskVo.setActApprovalRecord(properties.get("actapprovalrecord") != null ? properties.get("actapprovalrecord").toString() : "true");
        // 是否展示流程图
        taskVo.setActApprovalPng(properties.get("actapprovalpng") != null ? properties.get("actapprovalpng").toString() : "true");
        // 审批时是否可以上传附件
        taskVo.setUploadfile(properties.get("uploadfile") != null ? properties.get("uploadfile").toString() : "true");
        // activity节点描述
        taskVo.setActTaskDocumentation(properties.get("documentation") != null ? properties.get("documentation").toString() : "");


        // 自定义表单
        TaskDefinition taskDefinition = (TaskDefinition) properties.get("taskDefinition");
        Expression formKeyExpression = taskDefinition.getFormKeyExpression();
        if (formKeyExpression != null && StringUtils.isNotBlank(formKeyExpression.getExpressionText())) {
            taskVo.setActFormPath(formKeyExpression.getExpressionText());
        }


        // 获取其他的业务表单地址
        this.getFormPath(taskVo,activityImpl);

    }

    /**
     * 设置流程变量
     *
     * @param taskVo
     */
    public void setProcessVariables(TaskVo taskVo) {

        // 下一节点审批人
        if ("true".equals(taskVo.getSelectApproval()) && taskVo.getNextNodeApproval() != null) {
            taskService.setVariable(taskVo.getTaskId(), "actNextNodeApprover", taskVo.getNextNodeApproval().toJSONString());
        } else {
            taskService.removeVariable(taskVo.getTaskId(), "actNextNodeApprover");
        }

    }

    /**
     * 提交代办
     *
     * @param taskVo
     * @return
     */
    public AjaxResult complete(TaskVo taskVo){
        // 任务审批前校验
        AjaxResult checkResult = this.completeCheck(taskVo);
        if (checkResult != null) {
            return checkResult;
        }

        // 设置下一节点审批人接口调用
        String nextApproval = freeFlowCompleteImpl.getNextApproval(taskVo);

        // 设置流程变量
        this.setProcessVariables(taskVo);

        // 提交待办
        String taskId = this.completeTask(taskVo);

        // 绑定附件
        this.bindingFile(taskId, taskVo.getFileIdList());

        // 待办对接删除待办
        actDockingService.delTask(taskVo);

        // 校验流程是否到了某个特殊节点
        // actSpecialTaskService.checkSpecialNode(taskVo.getActId());

        // 发送待办提醒
        actSendTaskService.sendTask(taskVo.getActId(), "todoTask");

        // 默认发送抄送信息
        actSendCcService.sendCc(taskVo, taskId);


        String act_flow = ConfigUtils.get("act_flow");

        if (act_flow.contains(taskVo.getProcessDefKey())){
            //获取审批人
            List<HistoricActivityInstance> list = historyService.createHistoricActivityInstanceQuery().processInstanceId(taskVo.getActId()).activityType("userTask")
                    .orderByHistoricActivityInstanceStartTime().asc().list();


            List<String> strings = new ArrayList<>();
            List<SysUser> sysUsers = new ArrayList<>();
            String processDefinitionId = ActProcessUtils.getProcessDefinitionId(taskVo.getActId());
            ProcessInstance processInstance = ActProcessUtils.getProcessInstance(taskVo.getActId());
            if(processInstance!=null){
                ActivityImpl activityImpl = ActUtils.getActivityImpl(processDefinitionId, processInstance.getActivityId());
                // 节点名称
                Class<? extends ActivityBehavior> aClass = activityImpl.getActivityBehavior().getClass();
                try{
                    if (aClass == UserTaskActivityBehavior.class) {
                        UserTaskActivityBehavior activityBehavior = (UserTaskActivityBehavior) activityImpl.getActivityBehavior();
                        sysUsers = actProcessService.setUserTaskActivityBehavior(activityBehavior.getTaskDefinition(), taskVo.getActId());
                    } else if (aClass == ParallelMultiInstanceBehavior.class) {
                        ParallelMultiInstanceBehavior activityBehavior = (ParallelMultiInstanceBehavior) activityImpl.getActivityBehavior();
                        sysUsers = actProcessService.setExpression(activityBehavior.getCollectionExpression(), taskVo.getActId());
                    } else if (aClass == SequentialMultiInstanceBehavior.class) {
                        SequentialMultiInstanceBehavior activityBehavior = (SequentialMultiInstanceBehavior) activityImpl.getActivityBehavior();
                        sysUsers = actProcessService.setExpression(activityBehavior.getCollectionExpression(), taskVo.getActId());
                    }
                } catch (Exception e){
                    e.printStackTrace();
                }
                if(sysUsers !=null && sysUsers.size()>0){
                    for (SysUser sysUser : sysUsers) {
                        strings.add(sysUser.getUserName());
                    }
                } else{
                    for (HistoricActivityInstance historicActivityInstance : list) {
                        if(historicActivityInstance.getEndTime() == null && !StringUtils.equals(historicActivityInstance.getAssignee(),"-1")){
                            strings.add(historicActivityInstance.getAssignee());
                        }
                    }
                }

                flowInterfacesService.setActivityPar(taskVo.getActId(),StringUtils.isNotEmpty(strings)?  strings.toString().replaceAll("\\[","").replaceAll("]",""): "liuzhikun");

            }

            //设置提交后的线走向
            flowInterfacesService.setRelativeDataBatch(ActProcessUtils.completeSetParameters(taskVo), taskVo.getActId() );

            //流程提交接口调用
            boolean flowFlag = flowInterfacesService.complete(taskVo.getActId());
            if(!flowFlag){
                return AjaxResult.error("提交流程接口启动失败，请联系管理员进行查看！");
            }
        }

        //判断流程是否结束,如果结束了则执行结束后需调用的方法
        processEndService.whetherToEnd(taskVo.getActId());
        return AjaxResult.success();
    }

    /**
     * 提交代办
     *
     * @param taskVo 待办提交对象
     * @return 任务ID
     */
    public String completeTask(TaskVo taskVo) {

        // taskVo中放入待办任务对象
        taskVo.setViewRuTask(viewRuTaskService.get(taskVo.getId()));
        // taskVo中方式task对象
        taskVo.setTask(ActTaskUtils.getTask(taskVo.getId()));

        TaskComplete taskComplete = taskCompleteFactory.get(taskVo);

        // 设置任务变量
        taskComplete.setTaskVariables(taskVo.getTaskId(), taskVo.getOpinions());

        taskService.deleteComments(taskVo.getTaskId(), null);

        String taskId = taskComplete.complete(taskVo);

        // 如果审批人不是当前任务的处理人则记录委托处理
        this.entrustProcessing(taskVo, taskId);

        return taskId;
        // 自动签收接下来的任务
        //this.claimTask(taskVo.getActId());
    }

    /**
     * 如果审批人不是当前任务的处理人则记录委托处理
     *
     * @param taskVo
     */
    public void entrustProcessing(TaskVo taskVo, String taskId) {
        SysUser user = UserUtils.getUser();
        if (!user.getUserName().equals(taskVo.getViewRuTask().getAssignee()) && !taskVo.getJumpEntrust()) {
            wfActHiCommentService.addComment(taskVo.getActId(), taskId, "委托处理人:" + user.getNickName());

            WfActHiTask wfActHiTask = new WfActHiTask();
            wfActHiTask.setActId(taskVo.getActId());
            wfActHiTask.setActTaskId(taskVo.getTaskId());
            wfActHiTask.setActTaskKey(taskVo.getTaskKey());
            wfActHiTask.setActName(taskVo.getViewRuTask().getTaskName());
            wfActHiTask.setStartTime(taskVo.getViewRuTask().getStartTime());
            wfActHiTask.setApprovalTime(new Date(System.currentTimeMillis()));
            wfActHiTask.setSourceId(taskId);
            wfActHiTask.setSourceType("comment");
            wfActHiTask.setType("assist");
            wfActHiTask.setAssignee(user.getUserName());
            wfActHiTask.setHang("N");
            wfActHiTaskService.save(wfActHiTask);


        }
    }


    /**
     * 获取待办审批表单
     *
     * @param taskId
     * @return
     */
    public List<FormPropertyVo> getFormFiled(String taskId, String actTaskId,String actId,ActivityImpl activityImpl) {
        List<FormPropertyVo> res = new ArrayList<>();


       if (activityImpl.getProperties().get("formsql") != null){
           String dataId = ActUtils.getDataId(actId);
           String formsql = activityImpl.getProperties().get("formsql").toString().replace("${dataId}",dataId);
           List<Map<String, Object>> dataList = sqlDao.getDataList(formsql);
           for (Map<String, Object> map : dataList) {
               res.add(new FormPropertyVo(map));
           }

           return res;
       }


        TaskFormData taskFormData = formService.getTaskFormData(actTaskId);
        List<FormProperty> formProperties = taskFormData.getFormProperties();

        String taskType = wfActTaskVariableService.getValue(taskId, "taskType");

        for (FormProperty formProperty : formProperties) {
            if (!"applicantSupplement".equals(taskType) || !"审批结果".equals(formProperty.getName())){
                res.add(new FormPropertyVo(formProperty, taskId));
            }
        }
        return res;
    }





    /**
     * 签收当前流程的任务
     *
     * @param procInsId
     */
    public void claimTaskByProcInsId(String procInsId) {
        List<Task> currentTaskList = ActTaskUtils.getCurrentTaskList(procInsId);
        for (Task task : currentTaskList) {
            // 当前这个任务所有审批人，包含未签收的
            List<String> assigneeList = ActUtils.getAssigneeByTask(task);
            if (assigneeList.size() == 1 && StringUtils.isBlank(task.getAssignee())) {
                // 签收任务
                ActTaskUtils.claimTask(task.getId(), assigneeList.get(0));
            }
        }
    }


    /**
     * 签收任务
     *
     * @param taskId 待办ID
     * @return
     */
    public AjaxResult claimTask(String taskId) {
        String userName = UserUtils.getUser().getUserName();



        // 查看审批人列表中是否有当前用户，如果有的话签收流程
        List<String> assigneeList = ActUtils.getAssigneeByTask(taskId);
        ViewRuTask viewRuTask = viewRuTaskService.get(taskId);
        if (assigneeList.contains(userName)) {
            // 调用改派任务接口
            flowInterfacesService.reassign(viewRuTask,UserUtils.getUser());
            ActTaskUtils.claimTaskAndDelOtherTask(taskId, userName);
            return AjaxResult.setSuccessData(userName);
        } else {
            List<String> entrustUserNameList = wfEntrustTaskService.findEntrustUserName();
            for (String taskAssignee : assigneeList) {
                for (String entrustUserName : entrustUserNameList) {
                    if (taskAssignee.equals(entrustUserName)) {
                        // 调用改派任务接口
                        flowInterfacesService.reassign(viewRuTask,UserUtils.getUser());
                        ActTaskUtils.claimTaskAndDelOtherTask(taskId, taskAssignee);
                        return AjaxResult.setSuccessData(userName);
                    }
                }
            }

            return AjaxResult.error("您不在审批人列表中，无法签收流程");
        }
    }

    /**
     * 校验任务是否可以驳回
     * <p>
     * 涉及到前加签的不能驳回
     * 会签节点不能驳回
     *
     * @param taskId 任务ID
     * @return
     */
    public AjaxResult rejectedCheck(String taskId) {
        ViewRuTask viewRuTask = viewRuTaskService.get(taskId);

        if ("actTask".equals(viewRuTask.getType())) {
            return AjaxResult.setSuccessData(this.rejectedCheckActTask(viewRuTask));
        } else {
            return AjaxResult.setSuccessData(this.rejectedCheckAddTask(viewRuTask));
        }
    }

    /**
     * Activity任务驳回校验
     *
     * @param viewRuTask
     * @return
     */
    public String rejectedCheckActTask(ViewRuTask viewRuTask) {
        Task task = ActTaskUtils.getTask(viewRuTask.getId());
        ActivityImpl activityImpl = ActUtils.getActivityImpl(task.getProcessDefinitionId(), task.getTaskDefinitionKey());
        if (activityImpl.getActivityBehavior() instanceof ParallelMultiInstanceBehavior) {
            return "会签节点,无法进行驳回操作";
        }

        return "";
    }

    /**
     * 加签任务驳回校验
     *
     * @param viewRuTask
     * @return
     */
    public String rejectedCheckAddTask(ViewRuTask viewRuTask) {
        WfActRuTask wfActRuTask = wfActRuTaskDao.getById(viewRuTask.getId());


        if ("N".equals(wfActRuTask.getApprovalResults())) {
            return "前加签任务与因前加签产生的任务,无法进行驳回操作";
        }

//        List<WfActRuTask> wfActRuTaskList = wfActRuTaskService.findByActSourceId(wfActRuTask.getSourceId());
//        if(wfActRuTaskList.size() > 1){
//            return "";
//        }

        return "";
    }


    /**
     * 保存附件
     *
     * @param fileIdList
     */
    public void saveAttachment(JSONArray fileIdList, String taskId, String actId) {
        if (fileIdList != null) {
            for (int i = 0; i < fileIdList.size(); i++) {
                JSONObject fileJson = fileIdList.getJSONObject(i);
                FileBase fileBase = fileBaseService.getById(fileJson.getString("id"));
                Attachment attachment = taskService.createAttachment(fileBase.getFileType(), taskId, actId, fileBase.getName(), fileBase.getId(), "");
                taskService.saveAttachment(attachment);
            }
        }
    }

    /**
     * 绑定附件
     *
     * @param fileList
     * @param id
     */
    public void bindingFile(String id, JSONArray fileList) {
        List<FileBase> fileBaseList = new ArrayList<>();
        if (fileList != null) {
            for (int i = 0; i < fileList.size(); i++) {
                FileBase fileBase = fileBaseService.getById(fileList.getJSONObject(i).getString("id"));
                try {
                    JSONObject fileJson = fileList.getJSONObject(i);
                    // 补充目录的ID
                    fileBase.setDirectoryId(fileJson.get("directoryId").toString());
                    fileBase.setRemindUsers(fileJson.get("remindUsers") != null ? fileJson.get("remindUsers").toString() : null);
                    fileBase.setBusinessId(fileJson.get("businessId") != null ? fileJson.get("businessId").toString() : null);
                } catch (Exception e) {
                    LogUtils.error(e.getMessage(),e);
                }
                fileBaseList.add(fileBase);
            }
        }
        fileBaseService.bindingDataId(id, fileBaseList);
    }

    /**
     * 删除流程历史记录
     *
     * @param taskId 任务ID
     */
    public void delHiTask(String taskId) {
        actTaskDao.delHiActInst(taskId);
        actTaskDao.delHiTaskInst(taskId);
    }

    /**
     * 修改节点审批人
     * @param taskId
     * @param assignee
     */
    public void updateTaskAssignee(String taskId,String assignee){
        actTaskDao.updateHiActInstAssignee(assignee,taskId);
        actTaskDao.updateHiTaskAssignee(assignee,taskId);
    }


    /**
     * 获取待办数量
     *
     * @return
     */
    @Override
    public Long getCount(String userId) {
        //当前用户登录名
        return viewRuTaskService.findCount(userId);
    }

    /**
     * 查询来源节点用于驳回 (没有审批过的节点不让驳回)
     *
     * @param taskId
     * @return
     */
    public List<HistoryNodeVo> getHistoryNode(String taskId) {
        Task task = ActTaskUtils.getTask(taskId);
        ActivityImpl activityImpl = ActUtils.getActivityImpl(task);

        //查询历史记录(没有审批过的节点不让驳回)
        Map<String, Object> map = new HashMap<String, Object>();
        List<HistoricActivityInstance> historicList = historyService.createHistoricActivityInstanceQuery().processInstanceId(task.getProcessInstanceId()).list();
        for (HistoricActivityInstance historicActivityInstance : historicList) {
            map.put(historicActivityInstance.getActivityId(), historicActivityInstance.getActivityName());
        }

        //返回的list
        List<HistoryNodeVo> returnList = new ArrayList<HistoryNodeVo>();

        List<PvmTransition> tempOutgoingTransitions = new ArrayList<PvmTransition>();
        List<String> tempActivityId = new ArrayList<String>();

        //当前节点的activityId,如果是加签节点则取原节点的activityId
        String activityId = activityImpl.getId();
        String[] activityIds = activityId.split(":");
        if (activityIds.length == 3) {
            ActUtils.getActivityImpl(task.getProcessDefinitionId(), activityIds[1]);
        }
        tempActivityId.add(activityId);
        //当前节点的流入节点
        List<PvmTransition> incomingTransitions = activityImpl.getIncomingTransitions();

        //最多找50次，防止死循环
        int num = 0;
        while (incomingTransitions != null && incomingTransitions.size() > 0 && num < 50) {
            num++;
            for (PvmTransition pvmTransition : incomingTransitions) {
                PvmActivity destination = pvmTransition.getSource();
                if ("startEvent".equals(destination.getProperty("type")) || "parallelGateway".equals(destination.getProperty("type"))) {
                    return returnList;
                }

            }
            for (PvmTransition pvmTransition : incomingTransitions) {
                PvmActivity destination = pvmTransition.getSource();
                if (tempActivityId.contains(destination.getId())) {
                    continue;
                }

                if ("userTask".equals(destination.getProperty("type"))) {
                    if (!tempActivityId.contains(destination.getId()) && destination.getId().split(":").length != 3 && map.get(destination.getId()) != null) {
                        HistoryNodeVo historyNodeVo = new HistoryNodeVo();
                        historyNodeVo.setTaskId(destination.getId());
                        historyNodeVo.setTaskName(destination.getProperty("name").toString());
                        returnList.add(historyNodeVo);
                        tempActivityId.add(destination.getId());
                    }
                }
                tempOutgoingTransitions.addAll(destination.getIncomingTransitions());
            }
            incomingTransitions = tempOutgoingTransitions;
            tempOutgoingTransitions = new ArrayList<PvmTransition>();
        }
        Collections.reverse(returnList);
        return returnList;
    }

    /**
     * 交接流程
     *
     * @param source 原用户登录名
     * @param target 交接用户登录名
     * @return
     */
    @Transactional(readOnly = false)
    public String transferTodo(String source, String target) {

        // 查询原用户待办
        List<Task> list = taskService.createTaskQuery().taskAssignee(source).list();

        // 将原用户待办设置给交接用户
        for (Task task : list) {
            taskService.setAssignee(task.getId(), target);
        }

        //交接流程审批人
        actTaskDao.updateApproval(source, target);


        return "success";
    }

    /**
     * 交接流程
     * 消息来源 {@link com.anxin.sys.system.service.SysUserHandoverService#save}
     *
     * @param message
     * @return
     */
    @Override
    public boolean onMessage(String message) {
        JSONObject jsonObject = JSONObject.parseObject(message);
        String source = jsonObject.getString("source");
        String target = jsonObject.getString("target");
        this.transferTodo(source, target);
        return false;
    }

    /**
     * 删除历史任务
     *
     * @param taskId
     */
    public void delHiTaskInst(String taskId) {
        // 删除审批记录
        actTaskDao.delHiTaskInst(taskId);
        // 删除附件
        fileBaseDao.deleteFile("act_approval", taskId);
        // 删除抄送记录
        wfCcRecordDao.delByTaskId(taskId);
    }

    /**
     * 获取任务状态
     *
     * @param taskId 任务ID
     * @return
     */
    public AjaxResult getTaskStatus(String taskId) {
        AjaxResult ajaxResult = null;

        ViewRuTask viewRuTask = viewRuTaskService.get(taskId);
        if (viewRuTask != null) {
            ajaxResult = AjaxResult.setSuccessData("TODO");
        } else {
            ViewHiTask viewHiTask = viewHiTaskService.get(taskId);
            ajaxResult = AjaxResult.setSuccessData("HI");
            ajaxResult.put("actId", viewHiTask.getActId());
        }
        return ajaxResult;
    }

    /**
     * 任务提交前校验
     *
     * @param taskVo
     * @return
     */
    public AjaxResult completeCheck(TaskVo taskVo) {
        ViewRuTask viewRuTask = viewRuTaskService.get(taskVo.getId());
        if (viewRuTask == null || "-2".equals(viewRuTask.getAssignee())) {
            return AjaxResult.error("审批异常,任务已被处理或任务不存在");
        }

        return null;
    }

    /**
     * 保存补充意见
     */
    @Transactional(readOnly = false)
    public AjaxResult saveSupplementaryComments(TaskVo taskVo) {
        if (taskVo.getType().equals("actTask")) {
            actHiCommentService.deleteById(taskVo.getSupplementaryCommentsId());
            if (taskVo.getSupplementaryComments() != null && taskVo.getSupplementaryComments() != "") {
                ActHiComment comment = new ActHiComment();
                comment.setType("comment");
                comment.setTime(new Date());
                comment.setUserId(taskVo.getAssignee());
                comment.setTaskId(taskVo.getId());
                comment.setProcInstId(taskVo.getActId());
                comment.setAction("AddComment");
                comment.setMessage("补充意见:" + taskVo.getSupplementaryComments());
                comment.setFullMsg("补充意见:" + taskVo.getSupplementaryComments());
                actHiCommentService.save(comment);
            }
        } else {
            wfActHiCommentService.deleteById(taskVo.getSupplementaryCommentsId());
            if (taskVo.getSupplementaryComments() != null && taskVo.getSupplementaryComments() != "") {
                String supplementaryComments = taskVo.getSupplementaryComments();
                supplementaryComments = "补充意见:" + supplementaryComments;
                wfActHiCommentService.addComment(taskVo.getActId(), taskVo.getId(), supplementaryComments);
            }
        }

        fileBaseService.bindingDataId(taskVo.getId(), taskVo.getFileList());
        return AjaxResult.success();
    }

    /**
     * 查询补充意见
     *
     * @param taskVo
     * @return
     */
    public TaskVo findSupplementaryComments(TaskVo taskVo) {
        String message = null;
        if (taskVo.getType().equals("actTask")) {
            ActHiComment supplementaryComment = actHiCommentService.findSupplementaryComment(taskVo.getId(), taskVo.getActId());
            if (supplementaryComment != null) {
                message = supplementaryComment.getMessage();
                taskVo.setSupplementaryComments(message.substring(5));
                taskVo.setSupplementaryCommentsId(supplementaryComment.getId());
            }
        } else {
            WfActHiComment supplementaryComment = wfActHiCommentService.findSupplementaryComment(taskVo.getId(), taskVo.getActId());
            LogUtils.info("supplementaryComment" + supplementaryComment);
            if (supplementaryComment != null) {
                message = supplementaryComment.getMessage();
                taskVo.setSupplementaryComments(message.substring(5));
                taskVo.setSupplementaryCommentsId(supplementaryComment.getId());
            }
        }
        taskVo.setFileList(fileBaseService.findList(taskVo.getId(),"act_approval"));
        return taskVo;

    }

    /**
     * 修改已读未读状态
     *
     * @param taskVo
     */
    public void updateReadStatus(TaskVo taskVo) {
        String userId = UserUtils.getUser().getId();
        boolean readStatus = this.getReadStatus(taskVo.getId(), userId);
        if (readStatus) {
            WfTaskRead taskRead = new WfTaskRead();
            taskRead.setTaskId(taskVo.getId());
            taskRead.setActId(taskVo.getActId());
            taskRead.setTime(new Date());
            taskRead.setUserId(userId);
            wfTaskReadService.save(taskRead);
        }
    }

    /**
     * 查询是否已读
     *
     * @param id
     * @return
     */
    public boolean getReadStatus(String id, String userId) {
        WfTaskRead wfTaskRead = wfTaskReadService.getByTaskId(id, userId);
        return wfTaskRead == null;
    }

    /**
     *  表单暂存
     * @param taskVo
     * @return
     */
    @Transactional(readOnly = false)
    public TaskVo staging(TaskVo taskVo) {
        wfCommentStagingService.saveByTaskVo(taskVo);
        return taskVo;
    }

    /**
     * 获取审批意见暂存信息
     * @param taskVo
     */
    public void loadingStaging(TaskVo taskVo){
        wfCommentStagingService.loadingByTaskBy(taskVo);
    }


    /**
     * 历史任务管理
     * @param viewHiTask
     * @return
     */
    public List<ViewHiTask> hiTaskManager(ViewHiTask viewHiTask){
        viewHiTask.setOrderByColumn(" a.approval_time ");
        viewHiTask.setQueryType("hiTask");
        List<ViewHiTask> hiTaskList = viewHiTaskService.findList(viewHiTask);
        for (ViewHiTask hiTask : hiTaskList) {
            List<WfActHiComment> commentList = wfActHiCommentService.getCommentList(hiTask);
            hiTask.setCommentList(commentList);
            hiTask.setAssigneeName(UserUtils.getNickNameBuUserName(hiTask.getAssignee()));
        }
        return hiTaskList;
    }
}
